Les Demandes de Valeurs Foncières consituent un ensemble de données sur les transactions immobilières en France. Il est produit par la Direction Générale des Finances Publiques. Ces données ont été récupérées sur le lien suivant :
https://www.data.gouv.fr/fr/datasets/demandes-de-valeurs-foncieres/ https://www.tutorialspoint.com/plotly/plotly_quick_guide.htm
Les données sont réparties sur 5 années de 2016 à 2020.
Imports
!pip install plotly
Requirement already satisfied: plotly in /usr/local/lib/python3.7/dist-packages (4.4.1) Requirement already satisfied: six in /usr/local/lib/python3.7/dist-packages (from plotly) (1.15.0) Requirement already satisfied: retrying>=1.3.3 in /usr/local/lib/python3.7/dist-packages (from plotly) (1.3.3)
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import plotly.express as px
import plotly.graph_objects as go
import plotly
plotly.offline.init_notebook_mode()
#converter
from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()
import warnings
warnings.filterwarnings('ignore')
from google.colab import drive
drive.mount('/content/drive')
Drive already mounted at /content/drive; to attempt to forcibly remount, call drive.mount("/content/drive", force_remount=True).
df2020 = pd.read_csv("valeursfoncieres-2020.txt",sep='|')
df2019 = pd.read_csv("valeursfoncieres-2019.txt",sep='|')
#print(df2019.info())
On commence par observer les données : les colonnes non pertinentes en termes de contenu ou de libellé vont être enlevées par la suite.
#for col in df2020:
#print("###",col,"\n",df2020[col].value_counts())
On drop ensuite les colonnes que l'on ne souhaite pas utiliser.
df2020=df2020.drop(['Code service CH','Reference document','1 Articles CGI','2 Articles CGI','3 Articles CGI','4 Articles CGI','5 Articles CGI','No disposition','No voie','B/T/Q','Type de voie','Code voie','Voie','Code postal','Code commune','Prefixe de section','Section','No plan','No Volume','1er lot','Surface Carrez du 1er lot','2eme lot','Surface Carrez du 2eme lot','3eme lot','Surface Carrez du 3eme lot','4eme lot','Surface Carrez du 4eme lot','5eme lot','Surface Carrez du 5eme lot','Nombre de lots','Code type local','Identifiant local','Nature culture speciale'], axis=1)
df2019=df2019.drop(['Code service CH','Reference document','1 Articles CGI','2 Articles CGI','3 Articles CGI','4 Articles CGI','5 Articles CGI','No disposition','No voie','B/T/Q','Type de voie','Code voie','Voie','Code postal','Code commune','Prefixe de section','Section','No plan','No Volume','1er lot','Surface Carrez du 1er lot','2eme lot','Surface Carrez du 2eme lot','3eme lot','Surface Carrez du 3eme lot','4eme lot','Surface Carrez du 4eme lot','5eme lot','Surface Carrez du 5eme lot','Nombre de lots','Code type local','Identifiant local','Nature culture speciale'], axis=1)
#df2020.head()
On remplace les valeurs vides par des NaN.
df2020 = df2020.replace('', np.nan).fillna(0)
df2019 = df2019.replace('', np.nan).fillna(0)
#df2020.head()
On effectue les conversion nécessaires sur les données : les nombres entiers en entiers, les décimaux en float, les dates en datetime.
df2020["Nombre pieces principales"] = pd.to_numeric(df2020["Nombre pieces principales"],downcast='integer')
df2020["Valeur fonciere"] = df2020["Valeur fonciere"].replace({',': '.'}, regex=True)
df2020["Valeur fonciere"] = pd.to_numeric(df2020["Valeur fonciere"],downcast='float')
df2020['Code departement'] = df2020['Code departement'].astype(str)
df2020['Date mutation'] = pd.to_datetime(df2020['Date mutation'], format='%d/%m/%Y')
df2019["Nombre pieces principales"] = pd.to_numeric(df2019["Nombre pieces principales"],downcast='integer')
df2019["Valeur fonciere"] = df2019["Valeur fonciere"].replace({',': '.'}, regex=True)
df2019["Valeur fonciere"] = pd.to_numeric(df2019["Valeur fonciere"],downcast='float')
df2019['Code departement'] = df2019['Code departement'].astype(str)
df2019['Date mutation'] = pd.to_datetime(df2019['Date mutation'], format='%d/%m/%Y')
df2020.head()
| Date mutation | Nature mutation | Valeur fonciere | Commune | Code departement | Type local | Surface reelle bati | Nombre pieces principales | Nature culture | Surface terrain | |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2020-01-07 | Vente | 8000.0 | CEYZERIAT | 1 | 0 | 0.0 | 0 | T | 1061.0 |
| 1 | 2020-01-02 | Vente | 2175.0 | LAIZ | 1 | 0 | 0.0 | 0 | BT | 85.0 |
| 2 | 2020-01-02 | Vente | 2175.0 | LAIZ | 1 | 0 | 0.0 | 0 | T | 1115.0 |
| 3 | 2020-01-02 | Vente | 2175.0 | LAIZ | 1 | 0 | 0.0 | 0 | T | 1940.0 |
| 4 | 2020-01-02 | Vente | 2175.0 | LAIZ | 1 | 0 | 0.0 | 0 | T | 1148.0 |
On regarde les nombre de transactions sur l'ensemble de l'année 2020 à titre informatif.
print("Nombre de transactions sur 1 an : ",len(df2020.index))
Nombre de transactions sur 1 an : 2459560
On regarde ensuite l'évolution du nombre de transactions au cours de l'année.
#nb_ventes_per_date
df=df2020[['Nature mutation','Date mutation']]
df = df2020[df2020['Nature mutation']=='Vente'].groupby(df2020['Date mutation'].dt.weekofyear)['Nature mutation'].count().reset_index(name= 'Count')
df.head()
fig=px.line(df,x="Date mutation",y="Count")
fig.update_layout(title='Nombre de ventes par semaine en 2020',
xaxis_title='Semaine',
yaxis_title='Nombre de ventes')
fig.show()
On observe tout d'abord sur les 10 premières semaines une moyenne de 55 000 mutations par semaine. Ensuite, on observe une chute flagrante du nombre de mutation sur la période des semaines 13 à 19 environ, qui correspond à la période du premier confinement. Le reste de l'année est fait de violentes fluctuations, avec notamment une grosse baisse à la 33è semaine.
On analyse ensuite les données d'un point de vue financier. On commence par tracer un histogramme représentant la distribution des valeurs foncières des mutations.
# distribution_valeur_fonciere
df=df2020[["Valeur fonciere"]]
df=df[df["Valeur fonciere"] < 1000000]
fig = px.histogram(df, x="Valeur fonciere", title="Distribution des valeurs foncières des transactions en 2020")
fig.show()